package com.xwj.coupon.admin.repository.redis;

import cn.hutool.core.bean.BeanUtil;
import com.xwj.coupon.admin.common.constant.MerchantAdminRedisConstant;
import com.xwj.coupon.admin.dto.resp.CouponTemplateQueryRespDTO;
import com.xwj.coupon.admin.repository.mysql.entity.CouponTemplateDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: XuWenjie
 * @Date: 2025-08-14
 * @Description: CouponTemplateDao
 */
@Component
@Slf4j
public class CouponTemplateDao {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public void setCouponTemplate(CouponTemplateDO couponTemplateDO) {
        // 缓存预热：通过将数据库的记录序列化成 JSON 字符串放入 Redis 缓存
        CouponTemplateQueryRespDTO actualRespDTO = BeanUtil.toBean(couponTemplateDO, CouponTemplateQueryRespDTO.class);
        Map<String, Object> cacheTargetMap = BeanUtil.beanToMap(actualRespDTO, false, true);
        Map<String, String> actualCacheTargetMap = cacheTargetMap.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> {
                            if(entry.getValue() == null){
                                return "";
                            }
                            else{
                                if(entry.getValue() instanceof Date){
                                    return sdf.format(entry.getValue());
                                }
                                return entry.getValue().toString();
                            }
                        }
                ));
        String couponTemplateCacheKey = String.format(MerchantAdminRedisConstant.COUPON_TEMPLATE_KEY, couponTemplateDO.getId());

        // 通过 LUA 脚本执行设置 Hash 数据以及设置过期时间
        final String luaScript = "redis.call('HMSET', KEYS[1], unpack(ARGV, 1, #ARGV - 1)) " +
                "redis.call('EXPIREAT', KEYS[1], ARGV[#ARGV])";

        List<String> keys = Collections.singletonList(couponTemplateCacheKey);
        List<String> args = new ArrayList<>(actualCacheTargetMap.size() * 2 + 1);
        actualCacheTargetMap.forEach((key, value) -> {
            args.add(key);
            args.add(value);
        });

        // 优惠券活动过期时间转换为秒级别的 Unix 时间戳
        args.add(String.valueOf(couponTemplateDO.getValidEndTime().getTime() / 1000));

        log.info("优惠券模板缓存新增/更新keys：{}", keys);
        log.info("优惠券模板缓存新增/更新args：{}", args);
        // 执行 LUA 脚本
        stringRedisTemplate.execute(
                new DefaultRedisScript<>(luaScript, Long.class),
                keys,
                args.toArray()
        );
    }
}
